#include "StateTest.h"
#include "Task.h"
#include "streams.h"

CPPUNIT_TEST_SUITE_REGISTRATION( StateTest );

StateTest::StateTest()
{
    //ctor
}

StateTest::~StateTest()
{
    //dtor
}

void StateTest::Occupation ()
{
    TargetTask tasks;
    WeightTask task = std::make_pair(Ant(1,2),10);
    WeightTask previousTask;
    Location loc(10,10);

    CPPUNIT_ASSERT_MESSAGE( "tasks empty test" , false == taskOccuped(tasks, loc, previousTask));

    tasks[loc] = task;
    CPPUNIT_ASSERT_MESSAGE( "taskOccuped One value added" , true == taskOccuped(tasks, loc, previousTask));
    CPPUNIT_ASSERT_EQUAL( task.first.row, previousTask.first.row);
    CPPUNIT_ASSERT_EQUAL( task.first.col, previousTask.first.col);
    CPPUNIT_ASSERT_EQUAL( task.second, previousTask.second);

    ++loc.col;
    CPPUNIT_ASSERT_MESSAGE( "taskOccuped Task not exist" , false == taskOccuped(tasks, loc, previousTask));
}


void StateTest::distance()
{
    Location from(24,52);
    Location to(25,50);
    Location resolution(64,64);

    CPPUNIT_ASSERT_EQUAL( 3, distanceFast(from, to, resolution));

}

struct TruePredicate
{
    template <typename A, typename B>
    bool operator () (const A&, const B&) const {return true;}
};

void StateTest::FindTarget()
{
    Location source, food1(0,0), food2(3,3);
    LocationVector destinations;
    Location resolution(50,50);
    WeightTask result;

    CPPUNIT_ASSERT_MESSAGE( "destinations empty test" , false == FindNearestTarget<TruePredicate>(source, destinations, resolution, result, TruePredicate()));

/*0 1 2 3
0 * . a .
1 . . . .
2 . . . .
3 a . . *
4 . . . a
*/
    destinations.push_back(food1);
    destinations.push_back(food2);

    source = Location(0,2);
    CPPUNIT_ASSERT_EQUAL( true, FindNearestTarget(source, destinations, resolution, result, TruePredicate()));
    CPPUNIT_ASSERT_EQUAL( 2, result.second );
    CPPUNIT_ASSERT_EQUAL( food1, result.first );

    source = Location(4,3);
    CPPUNIT_ASSERT_EQUAL( true, FindNearestTarget(source, destinations, resolution, result, TruePredicate()));
    CPPUNIT_ASSERT_EQUAL( 1, result.second );
    CPPUNIT_ASSERT_EQUAL( food2, result.first );

    source = Location(3,0);
    CPPUNIT_ASSERT_EQUAL( true, FindNearestTarget(source, destinations, resolution, result, TruePredicate()));
    CPPUNIT_ASSERT_EQUAL( 3, result.second );
    CPPUNIT_ASSERT_EQUAL( food1, result.first );

    resolution = Location(5,4);
    CPPUNIT_ASSERT_EQUAL( 3, distanceFast(food2, food1, resolution));
    CPPUNIT_ASSERT_EQUAL( 3, distanceFast(food1, food2, resolution));

    CPPUNIT_ASSERT_EQUAL( 1, distanceFast(source, food2, resolution));

    CPPUNIT_ASSERT_EQUAL( true, FindNearestTarget(source, destinations, resolution, result, TruePredicate()));
    CPPUNIT_ASSERT_EQUAL( food2, result.first );
    CPPUNIT_ASSERT_EQUAL( 1, result.second );

}
